import json
import re

from django.conf import settings
from django.contrib.auth import login, authenticate
from django.http import JsonResponse
from django.views import View
from django.contrib.auth import logout

from aijia_zufang.settings.dev import logger, QINIU_DOMIN_PREFIX
from aijia_zufang.utils.image_storage import storage
from aijia_zufang.utils.response_code import RET
from aijia_zufang.utils.views import LoginRequiredJSONMixin
from apps.house.models import House
from apps.users.models import User

# 1.用户注册
class RegisterView(View):
    # 用户注册模块
    def post(self,request):
        '''
        接口文档：
        传递方式：post
        传递参数：mobile：         手机号         必传         字符串
                phonecode：      短信验证码      必传         字符串
                password：       密码1          必传         字符串
                password2：      密码2          必传         字符串
        链接地址：api/v1.0/user/register/
        响应方式：Json
        '''
        # 接收参数 获取参数
        json_dict =json.loads(request.body)
        mobile = json_dict.get('mobile')
        phonecode = json_dict.get('phonecode')
        password = json_dict.get('password')
        password2 = json_dict.get('password2')

        # 校验 参数
        # 1.是否全空，
        # 2.手机号，密码，短信，是否符合规则，
        # 3.密码2和密码1 是否相同

        # 1.是否全空，
        if not all ([mobile,phonecode,password,password2]):
            return JsonResponse({'errno': RET.PARAMERR , 'errmsg': "参数不能为空"})
        # # 判断手机号
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'errno': RET.PARAMERR , 'errmsg': "手机不能符合格式"})
        # # 判断密码是否符合规范
        if not re.match(r'^[A-Za-z0-9]{8,20}$',password):
            return JsonResponse({'errno': RET.PARAMERR, 'errmsg': "密码不符合规范"})
        # # 判断密码是否相同
        if password!=password2:
            return JsonResponse({'errno': RET.PARAMERR, 'errmsg': "密码不一致"})

        #写入数据库
        try:
            user = User.objects.create_user(
                mobile=mobile,
                username=mobile,
                password = password
            )
        except:
            return JsonResponse({'errno': RET.DATAERR , 'errmsg': "注册失败"})

        # 保持登录状态
        login(request,user)
        # 返回
        return JsonResponse({'errno': RET.OK, 'errmsg': "OK"})
    pass
# 2.用户登录
class Login(View):
    def post(self,request):
        '''
        接口文档
        传递路径：/api/v1.0/login/

        传递参数：mobile     字符串     必传      手机号
                password   字符串     必传      密码

        返回方式：json

                'errno': RET.OK,'errmsg': "登录成功"
        传递方式：POST

        '''
        # 1.获取参数
        json_dict = json.loads(request.body)
        mobile = json_dict.get('mobile')
        password = json_dict.get('password')

        # 校验参数
        if not all([mobile, password]):
            return JsonResponse({'errno': RET.PARAMERR, 'errmsg':'内容不能为空 '})

        # 修改
        if re.match(r'^1[3-9]\d{9}$', mobile):
            # 用户输入的账号是手机号:将USERNAME_FIELD指定为'mobile'字段
            User.USERNAME_FIELD = 'mobile'
            # 修改

        # 2. 从数据库查询出指定的用户
        try:
            user = User.objects.get(mobile=mobile)
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': RET.DBERR, 'errmsg': "用户不存在"})
        #
        # # 3. 校验密码
        if not user.check_password(password):
            return JsonResponse({'errno': RET.PWDERR, 'errmsg': "密码错误"})
        # user = authenticate(request,username=mobile,password=password) # authenticate主要是验证用户名和密码,这里是用手机号登录

        # 4. 保存用户登录状态
        login(request, user)

        # 5. 返回结果
        response = JsonResponse({'errno': RET.OK, 'errmsg': "登录成功"})
        response.set_cookie('username')
        return response
# 3.获取登录状态
class Session(View):
    '''
    获取登录状态接口文档
    请求方式：get
    请求路径：api/v1.0/session/
    请求参数：无
    响应：{"errno": "0", "errmsg": "OK", "data": {"user_id": 1, "name": "LQ"}}
    '''
    def get(self, request):
        """
        检测用户是否登录，如果登录，则返回用户的名和用户id
        """
        user = request.user
        if user.is_authenticated:
            data = {'user_id': user.id, 'name': user.username}
            return JsonResponse({'errno': RET.OK, 'errmsg': "OK", 'data': data})
        else:
            return JsonResponse({'code': 4101, 'errmsg': '用户未登录'})
# 3.用户实名
class UserAuthView(LoginRequiredJSONMixin,View):
    # 获取用户实名信息
    def get(self, request):
        '''
            获取用户实名信息接口文档
            请求方式：get
            请求路径：/api/v1.0/user/auth/
            请求参数：
            real_name   string   必传  用户真实姓名
            id_card     string   必传  用户身份证号
            响应：JSON
            {'errno': RET.OK, 'errmsg': "OK",'data':{'real_name':real_name,'id_card':id_card}}
            '''
        # 接收当前登录用户
        user = request.user
        # 返回
        return JsonResponse({

            "errno": 0,
            "errmsg": "success",
            "data": {'real_name':user.real_name,'id_card':user.id_card,}
        })

    '''
    设置用户实名信息接口文档
    请求方式：post
    请求路径：api/v1.0/user/auth/
    请求参数：
    real_name   string   必传  用户真实姓名
    id_card     string   必传  用户身份证号
    响应：JSON
    {'errno': RET.OK, 'errmsg': "OK"}
    '''

    # 设置用户实名信息
    def post(self,request):
        #接受用户信息
        user = request.user
        # 1.接受参数
        json_dict = request.body
        res_dict = json.loads(json_dict)
        real_name = res_dict.get('real_name')
        id_card = res_dict.get('id_card')
        # 2.校验参数
        if not all([real_name,id_card]):
            return JsonResponse({'errno':RET.PARAMERR, 'errmsg': "参数不全"})
        if not re.match('^[A-Za-z0-9\u4e00-\u9fa5\.·]{1,10}$',real_name):
            return JsonResponse({'errno': RET.PARAMERR, 'errmsg': "参数错误"})
        if not re.match('^(\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$',id_card):
            return JsonResponse({'errno':RET.PARAMERR, 'errmsg': "参数错误"})
        # 3. 更新用户的认证信息
        user.real_name = real_name
        user.id_card = id_card
        try:
            user.save()
        except Exception as e:
            return JsonResponse({'errno': RET.DBERR, 'errmsg': "保存数据失败"})
        # 4.返回
        return JsonResponse({'errno': RET.OK, 'errmsg': "OK"})
# 4.退出登录
class LogoutView(LoginRequiredJSONMixin,View):
    """
    路径：logout/,正确响应：code：0, errmsg:ok
    """
    def delete(self,requset):

        # 清理session
        logout(requset)
        # 创建response对象
        response = JsonResponse({'errno':RET.OK,'errmsg':'ok'})
        # 调用对象的delete_cookie方法，清除cookie
        response.delete_cookie('username')

        return response
# 5.获取用户信息+用户名修改
class UserProfileView(LoginRequiredJSONMixin,View):
    # 获取用户信息
    def get(self, request):

        # 接口文档
        """
        请求方式:get
        请求路径:api/v1.0/user/profile/
        请求参数: 无
        响应结果:json
        """
        # 1.接受参数
        user = request.user

        data = {
            'name': user.username,  # 用户名
            'avatar_url': user.avatar_url,  # url
            'mobile': user.mobile  # 手机号
        }
        # 返回响应
        return JsonResponse({'errno': 0, 'errmsg': 'OK', 'data': data})



    def post(self, request):
        """
        1. 获取到传入参数
        2. 将用户名信息更新到当前用户的模型中
        3. 返回结果
        """

        # 1. 获取到传入参数
        data_dict = json.loads(request.body)
        name = data_dict.get("name")
        if name is None:
            return JsonResponse({'errno': RET.PARAMERR, 'errmsg': "参数不完整"})

        # 2. 获取当前登录用户/更新用户名
        user = request.user
        try:

            user.username = name
            user.save()
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': RET.DBERR, 'errmsg': "保存数据失败"})

        return JsonResponse({'errno': RET.OK, 'errmsg': "OK"})
# 6.上传用户头像
class UploadAvatar(LoginRequiredJSONMixin,View):
    '''
    上传用户图像接口文档
    请求方式：post
    请求路径：/api/v1.0/user/avatar/
    请求参数：
    avatar
    file
    响应：JSON
    {'errno': RET.OK, 'errmsg': "OK",'data':avatar_url}
    '''
    def post(self, request):

        user = request.user

        # 判断有没有上传文件
        image_file = request.FILES.get('avatar')
        if not image_file:
            return JsonResponse({'errno': RET.PARAMERR, 'errmsg': '未上传文件'})
        # 将文件保存到七牛云
        image_data = image_file.read()
        try:
            file_name = storage(image_data)
        except Exception as e:
            logger(e)
            return JsonResponse({'errno': RET.PARAMERR, 'errmsg': '上传失败'})

        try:
            User.objects.filter(pk=user.id).update(avatar_url=file_name)
        except Exception as e:
            logger(e)
            return JsonResponse({{'errno': RET.PARAMERR, 'errmsg': '保存失败'}})
        # 返回
        avatar_url = QINIU_DOMIN_PREFIX + file_name
        user.avatar_url = avatar_url
        user.save()
        return JsonResponse({'errno': RET.OK, 'errmsg': "OK", 'data': {'avatar_url': avatar_url}})
# 7.我的房源
class UserHouseView(LoginRequiredJSONMixin, View):
    '''获取房源信息列表'''
    def get(self, request):
        # 1. 获取当前登录的用户
        user = request.user
        # 2. 查询当前用户返回的所有房屋数据信息
        try:
            # houses = House.objects.all(user=user)
            houses = user.house_set.all()
        # 2.1 如果没有数据的话或者数据显示出现问题,就返回数据报错
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': RET.DBERR, 'errmsg': '数据获取失败！'})

        # 3. 定义一个列表来存储数据
        houses_list = []

        # 4. 循环遍历出数据
        for house in houses:
            houses_list.append({
                'house_id': house.id,  # 主键 id
                'title': house.title,  # 房屋标题
                'price': house.price,  # 房屋单价
                'room_count': house.room_count,  # 房间数量
                'area_name': house.area.name,  # 房屋所在区域
                'address': house.address,  # 房屋所在的具体地址
                'ctime': house.create_time.strftime("%Y-%m-%d"),  # 房屋出售发布的时间
                'img_url': QINIU_DOMIN_PREFIX + house.index_image_url,  # 出售房屋样式图片存放地址
                'order_count': house.order_count,  # 房屋订单数量
                'user_avatar': house.user.avatar_url  # 当前登录用户的头像存放地址
            })

        # 5. 返回查询出来的结果给前端
        return JsonResponse({'errno': RET.OK, 'errmsg': '获取房源信息成功！', 'data': houses_list})
